package com.m3839.sdk.ym.widget.toast.draggable

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.util.DisplayMetrics
import android.view.MotionEvent
import android.view.View
import android.widget.LinearLayout

/**
 * author : Android 轮子哥
 * github : https://github.com/getActivity/XToast
 * time   : 2019/01/04
 * desc   : 拖拽后回弹处理实现类
 */
class SpringDraggable @JvmOverloads constructor(
    /** 回弹的方向  */
    private val mOrientation: Int = LinearLayout.HORIZONTAL
) :
    BaseDraggable() {
    /** 手指按下的坐标  */
    private var mViewDownX = 0f
    private var mViewDownY = 0f

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouch(v: View, event: MotionEvent): Boolean {
        val rawMoveX: Float
        val rawMoveY: Float
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                // 记录按下的位置（相对 View 的坐标）
                mViewDownX = event.x
                mViewDownY = event.y
            }
            MotionEvent.ACTION_MOVE -> {
                // 记录移动的位置（相对屏幕的坐标）
                rawMoveX = event.rawX - windowInvisibleWidth
                rawMoveY = event.rawY - windowInvisibleHeight

                // 更新移动的位置
                updateLocation(rawMoveX - mViewDownX, rawMoveY - mViewDownY)
            }
            MotionEvent.ACTION_UP -> {
                // 记录移动的位置（相对屏幕的坐标）
                rawMoveX = event.rawX - windowInvisibleWidth
                rawMoveY = event.rawY - windowInvisibleHeight
                when (mOrientation) {
                    LinearLayout.HORIZONTAL -> {
                        val rawFinalX: Float
                        // 获取当前屏幕的宽度
                        val screenWidth = screenWidth
                        rawFinalX = if (rawMoveX < screenWidth / 2f) {
                            // 回弹到屏幕左边
                            0f
                        } else {
                            // 回弹到屏幕右边
                            screenWidth.toFloat()
                        }
                        // 从移动的点回弹到边界上
                        startHorizontalAnimation(
                            rawMoveX - mViewDownX,
                            rawFinalX - mViewDownX,
                            rawMoveY - mViewDownY
                        )
                    }
                    LinearLayout.VERTICAL -> {
                        val rawFinalY: Float
                        // 获取当前屏幕的高度
                        val screenHeight = screenHeight
                        rawFinalY = if (rawMoveY < screenHeight / 2f) {
                            // 回弹到屏幕顶部
                            0f
                        } else {
                            // 回弹到屏幕底部
                            screenHeight.toFloat()
                        }
                        // 从移动的点回弹到边界上
                        startVerticalAnimation(
                            rawMoveX - mViewDownX,
                            rawMoveY - mViewDownY,
                            rawFinalY
                        )
                    }
                    else -> {
                    }
                }
                // 如果用户移动了手指，那么就拦截本次触摸事件，从而不让点击事件生效
                return isTouchMove(mViewDownX, event.x, mViewDownY, event.y)
            }
            else -> {
            }
        }
        return false
    }

    /**
     * 获取屏幕的宽度
     */
    private val screenWidth: Int
        private get() {
            val manager = windowManager!!
            val outMetrics = DisplayMetrics()
            manager.defaultDisplay.getMetrics(outMetrics)
            return outMetrics.widthPixels
        }

    /**
     * 获取屏幕的高度
     */
    private val screenHeight: Int
        private get() {
            val manager = windowManager!!
            val outMetrics = DisplayMetrics()
            manager.defaultDisplay.getMetrics(outMetrics)
            return outMetrics.heightPixels
        }

    /**
     * 执行水平回弹动画
     *
     * @param startX        X 轴起点坐标
     * @param endX          X 轴终点坐标
     * @param y             Y 轴坐标
     */
    private fun startHorizontalAnimation(
        startX: Float,
        endX: Float,
        y: Float
    ) {
        val animator = ValueAnimator.ofFloat(startX, endX)
        animator.duration = 500
        animator.addUpdateListener { animation ->
            updateLocation(
                animation.animatedValue as Float,
                y
            )
        }
        animator.start()
    }

    /**
     * 执行垂直回弹动画
     *
     * @param x             X 轴坐标
     * @param startY        Y 轴起点坐标
     * @param endY          Y 轴终点坐标
     */
    private fun startVerticalAnimation(
        x: Float,
        startY: Float,
        endY: Float
    ) {
        val animator = ValueAnimator.ofFloat(startY, endY)
        animator.duration = 500
        animator.addUpdateListener { animation ->
            updateLocation(
                x,
                animation.animatedValue as Float
            )
        }
        animator.start()
    }

    init {
        when (mOrientation) {
            LinearLayout.HORIZONTAL, LinearLayout.VERTICAL -> {
            }
            else -> throw IllegalArgumentException("You cannot pass in directions other than horizontal or vertical")
        }
    }
}